BUSINESS QUESTIONS: Note: ignore the fact there is no question 1, this is due to a formatting error 2. a) Is there are a trend in injuries By Region, and is there different peaks of times of year per region? b) Analysis on the types of animals that are injured, this also by Region – is there a species that is more liable to injury in certain regions? - (cat/dog by region) c) What is the outcome? Does this differ by region?

  1. Total call volume for complaint calls: How has this trended over time?
  2. Is there a particular animal being called about the most?
  3. Do particular suburbs have different type of complaint calls? Do they call about different animals? ((MAKE A LEAFLET MAP FOR THIS!))
  1. Business Intelligence – using the insights you have found, can you predict how this might look for the upcoming year?
library(tidyverse)
library(tsibble)

Attaching package: ‘tsibble’

The following object is masked from ‘package:lubridate’:

    interval

The following objects are masked from ‘package:base’:

    intersect, setdiff, union
library(forecast)
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 
This is forecast 8.20 
  Stackoverflow is a great place to get help on R issues:
  http://stackoverflow.com/tags/forecasting+r.
source("cleaning_script.R")
Rows: 31330 Columns: 7── Column specification ─────────────────────────────────────────────────────────
Delimiter: ","
chr (6): nature, animal_type, category, suburb, date_range, city
lgl (1): responsible_office
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.Warning: Expected 2 pieces. Missing pieces filled with `NA` in 5643 rows [7, 11, 12, 18, 19, 25, 27, 29, 30, 31, 39, 44, 52, 54, 66, 67, 74, 75, 78, 81, ...].Rows: 42413 Columns: 5── Column specification ─────────────────────────────────────────────────────────
Delimiter: ","
chr (5): Animal Type, Complaint Type, Date Received, Suburb, Electoral Division
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.Rows: 664 Columns: 12── Column specification ─────────────────────────────────────────────────────────
Delimiter: ","
chr  (2): animal_type, outcome
dbl (10): year, ACT, NSW, NT, QLD, SA, TAS, VIC, WA, Total
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Note; summer in Australia seasons: Summer: December - February Autumn: March - May Winter: June - August Spring: September - November

also: The ‘wet season’ in Australia’s North: November - April

https://www.mdpi.com/2076-2615/8/7/100 will useful reading for later, talk about the need to reduce euthanasia or similar and the effect this has on people

Intro: Introduce the point of the talk, talk about Australian RSPCA, talk about how the data was gathered (using the information from the websites), the PURPOSE of this investigation (which is to help the RSPCA know which areas/animals to focus their efforts on), as I’m introducing the datasets I can introduce the two different cities. First, we can talk a short bit about Australia as a whole, it’s climate, the kind of animals etc. The point here is to really set the scene before diving too deep into facts and figures, as especially a non-technical audience this will help keep them engaged and make a more holistic presentation. In my opinion, it’s always good to zoom out and see the big picture, rather than getting lost in the myopia of some csv files.

Townsville Intro: Townsville is a city on the north-eastern coast of Queensland, Australia. With a population of 180,820 as of June 2018, it is the largest settlement in North Queensland; it is unofficially considered its capital. [note: put a map of Australia with Queensland and Townsville highlighted here. Talk a little bit about the population density, urbanisation, climate, types of animals that are common here etc. Show some photos of the area too]

Brisbane Intro: Exact same as above

3.

  1. Total call volume for complaint calls: How has this trended over time?

First, let’s look at the Townsville animal complaints.

animal_complaints %>% 
  group_by(date_received) %>% 
  summarise(count = n()) %>% 
  ggplot(aes(x = date_received, y = count)) +
  geom_line() +
  scale_x_date(date_breaks = "6 months", date_labels = "%b-%y")

This shows some seasonality and also an increase then a decline. Each summer (in December) the calls are much lower, rising again each Winter. Using geom_smooth, we get:

animal_complaints %>% 
  group_by(date_received) %>% 
  summarise(count = n()) %>% 
  ggplot(aes(x = date_received, y = count)) +
  geom_smooth() +
  geom_point() +
  scale_x_date(date_breaks = "1 year", date_labels = "%y")

This shows a bit more clearly the general trend of call volume. From 2014 it steadily rises, peaking in 2017. Afterwards, it steadily declines to only slightly higher than where it started. It would be very difficult to say whether this trend will continue downward, go upward or stay relatively flat.

Note; if we have time or if it’s helpful, we will fix this graph so that quarters are properly displayed.

brisbane_complaints %>% 
  group_by(date) %>% 
  summarise(count = n()) %>% 
  ggplot(aes(x = date, y = count)) +
  geom_point() +
  geom_line() +
  scale_x_date(date_breaks = "3 months", date_labels = "%y")

Again, we see the seasonality of winter having more calls. The fact this is in both Brisbane and Townsville suggests a fairly general trend.

brisbane_complaints %>% 
  group_by(date) %>% 
  summarise(count = n()) %>% 
  ggplot(aes(x = date, y = count)) +
  geom_point() +
  geom_smooth() +
  scale_x_date(date_breaks = "1 year", date_labels = "20%y")

Other than declining a little over 2016, the number of calls sees a slow but steady increase towards 2020, being thousands more than it was in 2016 and 2017. So, the general trend is that the RSPCA are getting more complaints as time goes on. Now, this does not necessarily mean the line will continue to go up. We are also missing Q3 from 2016 so this skews the curve a little

3.

  1. Is there a particular animal being called about the most?
animal_complaints %>% 
  group_by(animal_type) %>% 
  ggplot(aes(x = animal_type)) +
  geom_bar()

The number of calls about dogs dwarf those about cats hugely. Let’s look at specific numbers:

animal_complaints %>% 
  group_by(animal_type) %>%
  count() %>% 
  summarise(n, 4094 / 38319)

So cats account for only 10% of the calls dogs do for Townsville! Let’s look at Brisbane:

brisbane_complaints %>% 
  group_by(type_of_animal) %>%
  count()

brisbane_complaints %>% 
  group_by(type_of_animal) %>%
  ggplot(aes(x = type_of_animal)) +
  geom_bar()

We have a lot more animal types here that we don’t in the previous data. We also have many calls about Attacks with no animal specified, many of which it is very likely they were involving dogs. However, we can’t say this for sure.

So that makes

4745 / 13334  # cats are 35% of the calls compared to dogs
[1] 0.3558572
# all other animals divided by dogs, leaving out unspecified (which we believe potentially contain a high proportion of dogs)
9457 / 13349
[1] 0.7084426

Most of the other animals have very small counts, interestingly foxes seem to make up a decent proportion of the calls regarding wild animals.

To answer the question however, it’s mainly dogs and cats, and especially dogs. Dogs are being called about more than any of the other animals combined (if we leave Unspecified to the side)

(Attack refers to the initial description of the complaint)

3.

  1. Do particular suburbs have different type of complaint calls? Do they call about different animals?

OK, so this one is difficult simply for the fact there is a huge amount of suburbs.

brisbane_complaints %>% 
  group_by(suburb) %>% 
  count()

# There is 192 suburbs! Certainly using a fill on a graph is not gonna work, neither is putting them on the x-axis on a bar graph.

animal_complaints %>% 
  group_by(suburb) %>% 
  count()
# 85 suburbs for Townsville

animal_complaints %>% 
  group_by(electoral_division) %>% 
  count()
# also 11 electoral divisions. Could we look at suburbs one electoral division at a time? Possibly

Idea: What about using leaflet to visualise types of complaint calls on a map?

This is more feasible with the Townsville datasets, as it has less suburbs and only 6 types of complaints. It may be necessary to try and wrangle the Brisbane data a little further to narrow down categories (for both type_of_animal and complaint_type)

FOR TOWNSVILLE WE HAVE: 85 different suburbs 6 complaint types 2 animal types

We want to break it down by suburb and complaint type, and then by suburb and animal type

animal_complaints %>% 
  ggplot(aes(x = suburb, fill = animal_type)) +
  geom_bar(position = "fill") +
  coord_flip() +
  scale_x_discrete(guide = guide_axis(n.dodge = 5))

animal_complaints %>% 
  ggplot(aes(x = suburb, fill =complaint_type)) +
  geom_bar(position = "fill") 

  #coord_flip() +
  #scale_x_discrete(guide = guide_axis(n.dodge = 5))

The challenge again, is having too many suburbs that we can’t get any useful information out of the graphs

animal_complaints %>% 
  group_by(suburb) %>% 
  count(sort = TRUE)

# let's drop any suburbs with less than 200 cases

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), animal_type) %>% 
  filter(count >= 500) %>% 
  ggplot(aes(x = suburb, y = count, fill = animal_type)) +
  geom_col() +
  coord_flip()
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

The highest count by quite a large margin is unallocated to a specific suburb.

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), animal_type) %>% 
  filter(count >= 500) %>% 
  ggplot(aes(x = suburb, y = count, fill = animal_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

At a glance, there’s no big difference on animal types. All the suburbs have a large majority of dogs. Could we do a hypothesis test to see if there is a statistically significant difference?

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), animal_type) %>% 
  filter(count < 500 & count > 100) %>% 
  ggplot(aes(x = suburb, y = count, fill = animal_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

Looking at the lower end of the population, we see an outlier. Townsville City has way more cats than any of the other suburbs. In fact, it’s almost 50/50!

Now still looking at the Townsville dataset, we’ll break it down by complaint type:

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count >= 500 & count <= 4000) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

Now for the lower end of the count:

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count < 500 & count > 50) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

I’m not sure much can be gleamed with so many complaint_types. Let’s try focusing more specifically.

One thing to note here, is the vast variation in tolerance for noise. Most categories are consistent except this one. Cluden for example has a small percentage of noise complaints,while Bohle Plains has a huge percentage. This requires more investigation to figure out the root cause of this:

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count >= 500) %>% 
  filter(complaint_type == "Noise" | (complaint_type == "Attack")) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count >= 500) %>% 
  filter(complaint_type == "Noise" | (complaint_type == "Aggressive Animal")) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count >= 500) %>% 
  filter(complaint_type == "Wandering" | (complaint_type == "Aggressive Animal")) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count >= 500) %>% 
  filter(complaint_type == "Enclosure" | (complaint_type == "Noise")) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

For the less than 500 greater than 50 groups:

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count < 500 & count > 100) %>% 
  filter(complaint_type == "Noise" | (complaint_type == "Attack")) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count < 500 & count > 100) %>%  
  filter(complaint_type == "Noise" | (complaint_type == "Aggressive Animal")) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count < 500 & count > 100) %>% 
  filter(complaint_type == "Wandering" | (complaint_type == "Aggressive Animal")) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() 
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type) %>% 
  filter(count < 500 & count > 100) %>% 
  #filter(complaint_type == "Enclosure" | (complaint_type == "Noise")) %>% 
  ggplot(aes(x = suburb, y = count, fill = complaint_type)) +
  geom_col(position = "fill") +
  coord_flip() +
  facet_wrap(~ suburb)
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type, animal_type) %>% 
  filter(count < 500 & count > 100) %>% 
  ggplot(aes(x = complaint_type, y = count, fill = complaint_type)) +
  geom_col() +
  facet_wrap(~ suburb)
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

From this graph, we can see that Hyde Park has a disproportionate amount of private impounds, while Bohle plains has more noise complaints.

Potential hypothesis test:

That the level of private impounds in Hyde Park being greater is statistically significant.

That the level of noise in Bohle Plains being greater is statistically significant.

animal_complaints %>% 
  group_by(suburb) %>% 
  count() %>% 
  filter(n < 500 & n > 100)

Let’s look at the suburbs with much higher complaints now:

animal_complaints %>% 
  group_by(suburb) %>% 
  summarise(count = n(), complaint_type, animal_type) %>% 
  filter(count >= 500 & count <4000) %>% 
  ggplot(aes(x = complaint_type, y = count, fill = complaint_type)) +
  geom_col() +
  facet_wrap(~ suburb)
`summarise()` has grouped output by 'suburb'. You can override using the `.groups` argument.

2. a) Is there are a trend in injuries By Region, and is there different peaks of times of year per region?

It’s impossible to say if there’s different peaks of times of yer per region, as we only have the data for the year as a whole. Unless we look at Suburb rather than region, and break this down by time. However, I think it’d be good to use the general Autralia (nationwide) data.

animal_outcomes %>% 
  group_by(region) %>% 
  ggplot(aes(x = region, y = number_of_occurences, fill = outcome, col = outcome)) +
  geom_col(position = "fill")

animal_outcomes %>% 
  group_by(region, year) %>% 
  summarise(count = n())
`summarise()` has grouped output by 'region'. You can override using the `.groups` argument.
LS0tCnRpdGxlOiAiQW5hbHlzaXMiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkJVU0lORVNTIFFVRVNUSU9OUzoKTm90ZTogaWdub3JlIHRoZSBmYWN0IHRoZXJlIGlzIG5vIHF1ZXN0aW9uIDEsIHRoaXMgaXMgZHVlIHRvIGEgZm9ybWF0dGluZyBlcnJvcgoyLiAKYSkgSXMgdGhlcmUgYXJlIGEgdHJlbmQgaW4gaW5qdXJpZXMgQnkgUmVnaW9uLCBhbmQgaXMgdGhlcmUgZGlmZmVyZW50IHBlYWtzIG9mIHRpbWVzIG9mIHllYXIgcGVyIHJlZ2lvbj8KYikgQW5hbHlzaXMgb24gdGhlIHR5cGVzIG9mIGFuaW1hbHMgdGhhdCBhcmUgaW5qdXJlZCwgdGhpcyBhbHNvIGJ5IFJlZ2lvbiDigJMgaXMgdGhlcmUgYSBzcGVjaWVzIHRoYXQgaXMgbW9yZSBsaWFibGUgdG8gaW5qdXJ5IGluIGNlcnRhaW4gcmVnaW9ucz8gLSAoY2F0L2RvZyBieSByZWdpb24pCmMpIFdoYXQgaXMgdGhlIG91dGNvbWU/IERvZXMgdGhpcyBkaWZmZXIgYnkgcmVnaW9uPwoKMy4KYSkgVG90YWwgY2FsbCB2b2x1bWUgZm9yIGNvbXBsYWludCBjYWxsczogSG93IGhhcyB0aGlzIHRyZW5kZWQgb3ZlciB0aW1lPwpiKSBJcyB0aGVyZSBhIHBhcnRpY3VsYXIgYW5pbWFsIGJlaW5nIGNhbGxlZCBhYm91dCB0aGUgbW9zdD8KYykgRG8gcGFydGljdWxhciBzdWJ1cmJzIGhhdmUgZGlmZmVyZW50IHR5cGUgb2YgY29tcGxhaW50IGNhbGxzPyBEbyB0aGV5IGNhbGwgYWJvdXQgZGlmZmVyZW50IGFuaW1hbHM/ICgoTUFLRSBBIExFQUZMRVQgTUFQIEZPUiBUSElTISkpCgo0LgpCdXNpbmVzcyBJbnRlbGxpZ2VuY2Ug4oCTIHVzaW5nIHRoZSBpbnNpZ2h0cyB5b3UgaGF2ZSBmb3VuZCwgY2FuIHlvdSBwcmVkaWN0IGhvdyB0aGlzIG1pZ2h0IGxvb2sgZm9yIHRoZSB1cGNvbWluZyB5ZWFyPwoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRzaWJibGUpCmxpYnJhcnkoZm9yZWNhc3QpCnNvdXJjZSgiY2xlYW5pbmdfc2NyaXB0LlIiKQpgYGAKCk5vdGU7IHN1bW1lciBpbiBBdXN0cmFsaWEgc2Vhc29uczoKU3VtbWVyOiBEZWNlbWJlciAtIEZlYnJ1YXJ5CkF1dHVtbjogTWFyY2ggLSBNYXkKV2ludGVyOiBKdW5lIC0gQXVndXN0ClNwcmluZzogU2VwdGVtYmVyIC0gTm92ZW1iZXIKCmFsc286IFRoZSAnd2V0IHNlYXNvbicgaW4gQXVzdHJhbGlhJ3MgTm9ydGg6IE5vdmVtYmVyIC0gQXByaWwKCmh0dHBzOi8vd3d3Lm1kcGkuY29tLzIwNzYtMjYxNS84LzcvMTAwICAgd2lsbCB1c2VmdWwgcmVhZGluZyBmb3IgbGF0ZXIsIHRhbGsgYWJvdXQgdGhlIG5lZWQgdG8gcmVkdWNlIGV1dGhhbmFzaWEgb3Igc2ltaWxhciBhbmQgdGhlIGVmZmVjdCB0aGlzIGhhcyBvbiBwZW9wbGUKCkludHJvOgpJbnRyb2R1Y2UgdGhlIHBvaW50IG9mIHRoZSB0YWxrLCB0YWxrIGFib3V0IEF1c3RyYWxpYW4gUlNQQ0EsIHRhbGsgYWJvdXQgaG93IHRoZSBkYXRhIHdhcyBnYXRoZXJlZCAodXNpbmcgdGhlIGluZm9ybWF0aW9uIGZyb20gdGhlIHdlYnNpdGVzKSwgdGhlIFBVUlBPU0Ugb2YgdGhpcyBpbnZlc3RpZ2F0aW9uICh3aGljaCBpcyB0byBoZWxwIHRoZSBSU1BDQSBrbm93IHdoaWNoIGFyZWFzL2FuaW1hbHMgdG8gZm9jdXMgdGhlaXIgZWZmb3J0cyBvbiksIGFzIEknbSBpbnRyb2R1Y2luZyB0aGUgZGF0YXNldHMgSSBjYW4gaW50cm9kdWNlIHRoZSB0d28gZGlmZmVyZW50IGNpdGllcy4gRmlyc3QsIHdlIGNhbiB0YWxrIGEgc2hvcnQgYml0IGFib3V0IEF1c3RyYWxpYSBhcyBhIHdob2xlLCBpdCdzIGNsaW1hdGUsIHRoZSBraW5kIG9mIGFuaW1hbHMgZXRjLiBUaGUgcG9pbnQgaGVyZSBpcyB0byByZWFsbHkgc2V0IHRoZSBzY2VuZSBiZWZvcmUgZGl2aW5nIHRvbyBkZWVwIGludG8gZmFjdHMgYW5kIGZpZ3VyZXMsIGFzIGVzcGVjaWFsbHkgYSBub24tdGVjaG5pY2FsIGF1ZGllbmNlIHRoaXMgd2lsbCBoZWxwIGtlZXAgdGhlbSBlbmdhZ2VkIGFuZCBtYWtlIGEgbW9yZSBob2xpc3RpYyBwcmVzZW50YXRpb24uIEluIG15IG9waW5pb24sIGl0J3MgYWx3YXlzIGdvb2QgdG8gem9vbSBvdXQgYW5kIHNlZSB0aGUgYmlnIHBpY3R1cmUsIHJhdGhlciB0aGFuIGdldHRpbmcgbG9zdCBpbiB0aGUgbXlvcGlhIG9mIHNvbWUgY3N2IGZpbGVzLgoKVG93bnN2aWxsZSBJbnRybzoKVG93bnN2aWxsZSBpcyBhIGNpdHkgb24gdGhlIG5vcnRoLWVhc3Rlcm4gY29hc3Qgb2YgUXVlZW5zbGFuZCwgQXVzdHJhbGlhLiBXaXRoIGEgcG9wdWxhdGlvbiBvZiAxODAsODIwIGFzIG9mIEp1bmUgMjAxOCwgaXQgaXMgdGhlIGxhcmdlc3Qgc2V0dGxlbWVudCBpbiBOb3J0aCBRdWVlbnNsYW5kOyBpdCBpcyB1bm9mZmljaWFsbHkgY29uc2lkZXJlZCBpdHMgY2FwaXRhbC4gW25vdGU6IHB1dCBhIG1hcCBvZiBBdXN0cmFsaWEgd2l0aCBRdWVlbnNsYW5kIGFuZCBUb3duc3ZpbGxlIGhpZ2hsaWdodGVkIGhlcmUuIFRhbGsgYSBsaXR0bGUgYml0IGFib3V0IHRoZSBwb3B1bGF0aW9uIGRlbnNpdHksIHVyYmFuaXNhdGlvbiwgY2xpbWF0ZSwgdHlwZXMgb2YgYW5pbWFscyB0aGF0IGFyZSBjb21tb24gaGVyZSBldGMuIFNob3cgc29tZSBwaG90b3Mgb2YgdGhlIGFyZWEgdG9vXQoKQnJpc2JhbmUgSW50cm86CkV4YWN0IHNhbWUgYXMgYWJvdmUKCiMjIyAzLgphKSBUb3RhbCBjYWxsIHZvbHVtZSBmb3IgY29tcGxhaW50IGNhbGxzOiBIb3cgaGFzIHRoaXMgdHJlbmRlZCBvdmVyIHRpbWU/CgpGaXJzdCwgbGV0J3MgbG9vayBhdCB0aGUgVG93bnN2aWxsZSBhbmltYWwgY29tcGxhaW50cy4KYGBge3J9CmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShkYXRlX3JlY2VpdmVkKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZV9yZWNlaXZlZCwgeSA9IGNvdW50KSkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiNiBtb250aHMiLCBkYXRlX2xhYmVscyA9ICIlYi0leSIpCmBgYApUaGlzIHNob3dzIHNvbWUgc2Vhc29uYWxpdHkgYW5kIGFsc28gYW4gaW5jcmVhc2UgdGhlbiBhIGRlY2xpbmUuIEVhY2ggc3VtbWVyIChpbiBEZWNlbWJlcikgdGhlIGNhbGxzIGFyZSBtdWNoIGxvd2VyLCByaXNpbmcgYWdhaW4gZWFjaCBXaW50ZXIuIFVzaW5nIGdlb21fc21vb3RoLCB3ZSBnZXQ6CgpgYGB7cn0KYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KGRhdGVfcmVjZWl2ZWQpICU+JSAKICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkYXRlX3JlY2VpdmVkLCB5ID0gY291bnQpKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMSB5ZWFyIiwgZGF0ZV9sYWJlbHMgPSAiJXkiKQpgYGAKClRoaXMgc2hvd3MgYSBiaXQgbW9yZSBjbGVhcmx5IHRoZSBnZW5lcmFsIHRyZW5kIG9mIGNhbGwgdm9sdW1lLiBGcm9tIDIwMTQgaXQgc3RlYWRpbHkgcmlzZXMsIHBlYWtpbmcgaW4gMjAxNy4gQWZ0ZXJ3YXJkcywgaXQgc3RlYWRpbHkgZGVjbGluZXMgdG8gb25seSBzbGlnaHRseSBoaWdoZXIgdGhhbiB3aGVyZSBpdCBzdGFydGVkLiBJdCB3b3VsZCBiZSB2ZXJ5IGRpZmZpY3VsdCB0byBzYXkgd2hldGhlciB0aGlzIHRyZW5kIHdpbGwgY29udGludWUgZG93bndhcmQsIGdvIHVwd2FyZCBvciBzdGF5IHJlbGF0aXZlbHkgZmxhdC4KCgoKCgoKCk5vdGU7IGlmIHdlIGhhdmUgdGltZSBvciBpZiBpdCdzIGhlbHBmdWwsIHdlIHdpbGwgZml4IHRoaXMgZ3JhcGggc28gdGhhdCBxdWFydGVycyBhcmUgcHJvcGVybHkgZGlzcGxheWVkLgpgYGB7cn0KYnJpc2JhbmVfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSBjb3VudCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fbGluZSgpICsKICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMyBtb250aHMiLCBkYXRlX2xhYmVscyA9ICIleSIpCmBgYAoKQWdhaW4sIHdlIHNlZSB0aGUgc2Vhc29uYWxpdHkgb2Ygd2ludGVyIGhhdmluZyBtb3JlIGNhbGxzLiBUaGUgZmFjdCB0aGlzIGlzIGluIGJvdGggQnJpc2JhbmUgYW5kIFRvd25zdmlsbGUgc3VnZ2VzdHMgYSBmYWlybHkgZ2VuZXJhbCB0cmVuZC4KCmBgYHtyfQpicmlzYmFuZV9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IGNvdW50KSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9zbW9vdGgoKSArCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjEgeWVhciIsIGRhdGVfbGFiZWxzID0gIjIwJXkiKQpgYGAKCk90aGVyIHRoYW4gZGVjbGluaW5nIGEgbGl0dGxlIG92ZXIgMjAxNiwgdGhlIG51bWJlciBvZiBjYWxscyBzZWVzIGEgc2xvdyBidXQgc3RlYWR5IGluY3JlYXNlIHRvd2FyZHMgMjAyMCwgYmVpbmcgdGhvdXNhbmRzIG1vcmUgdGhhbiBpdCB3YXMgaW4gMjAxNiBhbmQgMjAxNy4gU28sIHRoZSBnZW5lcmFsIHRyZW5kIGlzIHRoYXQgdGhlIFJTUENBIGFyZSBnZXR0aW5nIG1vcmUgY29tcGxhaW50cyBhcyB0aW1lIGdvZXMgb24uIE5vdywgdGhpcyBkb2VzIG5vdCBuZWNlc3NhcmlseSBtZWFuIHRoZSBsaW5lIHdpbGwgY29udGludWUgdG8gZ28gdXAuIFdlIGFyZSBhbHNvIG1pc3NpbmcgUTMgZnJvbSAyMDE2IHNvIHRoaXMgc2tld3MgdGhlIGN1cnZlIGEgbGl0dGxlCgoKCiMjIyAzLgpiKSBJcyB0aGVyZSBhIHBhcnRpY3VsYXIgYW5pbWFsIGJlaW5nIGNhbGxlZCBhYm91dCB0aGUgbW9zdD8KCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoYW5pbWFsX3R5cGUpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBhbmltYWxfdHlwZSkpICsKICBnZW9tX2JhcigpCmBgYAoKVGhlIG51bWJlciBvZiBjYWxscyBhYm91dCBkb2dzIGR3YXJmIHRob3NlIGFib3V0IGNhdHMgaHVnZWx5LiBMZXQncyBsb29rIGF0IHNwZWNpZmljIG51bWJlcnM6CmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoYW5pbWFsX3R5cGUpICU+JQogIGNvdW50KCkgJT4lIAogIHN1bW1hcmlzZShuLCA0MDk0IC8gMzgzMTkpCmBgYAoKU28gY2F0cyBhY2NvdW50IGZvciBvbmx5IDEwJSBvZiB0aGUgY2FsbHMgZG9ncyBkbyBmb3IgVG93bnN2aWxsZSEgTGV0J3MgbG9vayBhdCBCcmlzYmFuZToKCmBgYHtyfQpicmlzYmFuZV9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieSh0eXBlX29mX2FuaW1hbCkgJT4lCiAgY291bnQoKQoKYnJpc2JhbmVfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkodHlwZV9vZl9hbmltYWwpICU+JQogIGdncGxvdChhZXMoeCA9IHR5cGVfb2ZfYW5pbWFsKSkgKwogIGdlb21fYmFyKCkKYGBgCgpXZSBoYXZlIGEgbG90IG1vcmUgYW5pbWFsIHR5cGVzIGhlcmUgdGhhdCB3ZSBkb24ndCBpbiB0aGUgcHJldmlvdXMgZGF0YS4gV2UgYWxzbyBoYXZlIG1hbnkgY2FsbHMgYWJvdXQgQXR0YWNrcyB3aXRoIG5vIGFuaW1hbCBzcGVjaWZpZWQsIG1hbnkgb2Ygd2hpY2ggaXQgaXMgdmVyeSBsaWtlbHkgdGhleSB3ZXJlIGludm9sdmluZyBkb2dzLiBIb3dldmVyLCB3ZSBjYW4ndCBzYXkgdGhpcyBmb3Igc3VyZS4KClNvIHRoYXQgbWFrZXMgCmBgYHtyfQo0NzQ1IC8gMTMzMzQgICMgY2F0cyBhcmUgMzUlIG9mIHRoZSBjYWxscyBjb21wYXJlZCB0byBkb2dzCgoKCiMgYWxsIG90aGVyIGFuaW1hbHMgZGl2aWRlZCBieSBkb2dzLCBsZWF2aW5nIG91dCB1bnNwZWNpZmllZCAod2hpY2ggd2UgYmVsaWV2ZSBwb3RlbnRpYWxseSBjb250YWluIGEgaGlnaCBwcm9wb3J0aW9uIG9mIGRvZ3MpCjk0NTcgLyAxMzM0OQpgYGAKCk1vc3Qgb2YgdGhlIG90aGVyIGFuaW1hbHMgaGF2ZSB2ZXJ5IHNtYWxsIGNvdW50cywgaW50ZXJlc3RpbmdseSBmb3hlcyBzZWVtIHRvIG1ha2UgdXAgYSBkZWNlbnQgcHJvcG9ydGlvbiBvZiB0aGUgY2FsbHMgcmVnYXJkaW5nIHdpbGQgYW5pbWFscy4KClRvIGFuc3dlciB0aGUgcXVlc3Rpb24gaG93ZXZlciwgaXQncyBtYWlubHkgZG9ncyBhbmQgY2F0cywgYW5kIGVzcGVjaWFsbHkgZG9ncy4gRG9ncyBhcmUgYmVpbmcgY2FsbGVkIGFib3V0IG1vcmUgdGhhbiBhbnkgb2YgdGhlIG90aGVyIGFuaW1hbHMgY29tYmluZWQgKGlmIHdlIGxlYXZlIFVuc3BlY2lmaWVkIHRvIHRoZSBzaWRlKQoKKEF0dGFjayByZWZlcnMgdG8gdGhlIGluaXRpYWwgZGVzY3JpcHRpb24gb2YgdGhlIGNvbXBsYWludCkKCgojIyMgMy4gCmMpIERvIHBhcnRpY3VsYXIgc3VidXJicyBoYXZlIGRpZmZlcmVudCB0eXBlIG9mIGNvbXBsYWludCBjYWxscz8gRG8gdGhleSBjYWxsIGFib3V0IGRpZmZlcmVudCBhbmltYWxzPwoKT0ssIHNvIHRoaXMgb25lIGlzIGRpZmZpY3VsdCBzaW1wbHkgZm9yIHRoZSBmYWN0IHRoZXJlIGlzIGEgaHVnZSBhbW91bnQgb2Ygc3VidXJicy4KYGBge3J9CmJyaXNiYW5lX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIGNvdW50KCkKCiMgVGhlcmUgaXMgMTkyIHN1YnVyYnMhIENlcnRhaW5seSB1c2luZyBhIGZpbGwgb24gYSBncmFwaCBpcyBub3QgZ29ubmEgd29yaywgbmVpdGhlciBpcyBwdXR0aW5nIHRoZW0gb24gdGhlIHgtYXhpcyBvbiBhIGJhciBncmFwaC4KCmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShzdWJ1cmIpICU+JSAKICBjb3VudCgpCiMgODUgc3VidXJicyBmb3IgVG93bnN2aWxsZQoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KGVsZWN0b3JhbF9kaXZpc2lvbikgJT4lIAogIGNvdW50KCkKIyBhbHNvIDExIGVsZWN0b3JhbCBkaXZpc2lvbnMuIENvdWxkIHdlIGxvb2sgYXQgc3VidXJicyBvbmUgZWxlY3RvcmFsIGRpdmlzaW9uIGF0IGEgdGltZT8gUG9zc2libHkKYGBgCgpJZGVhOiBXaGF0IGFib3V0IHVzaW5nIGxlYWZsZXQgdG8gdmlzdWFsaXNlIHR5cGVzIG9mIGNvbXBsYWludCBjYWxscyBvbiBhIG1hcD8KClRoaXMgaXMgbW9yZSBmZWFzaWJsZSB3aXRoIHRoZSBUb3duc3ZpbGxlIGRhdGFzZXRzLCBhcyBpdCBoYXMgbGVzcyBzdWJ1cmJzIGFuZCBvbmx5IDYgdHlwZXMgb2YgY29tcGxhaW50cy4gSXQgbWF5IGJlIG5lY2Vzc2FyeSB0byB0cnkgYW5kIHdyYW5nbGUgdGhlIEJyaXNiYW5lIGRhdGEgYSBsaXR0bGUgZnVydGhlciB0byBuYXJyb3cgZG93biBjYXRlZ29yaWVzIChmb3IgYm90aCB0eXBlX29mX2FuaW1hbCBhbmQgY29tcGxhaW50X3R5cGUpCgpGT1IgVE9XTlNWSUxMRSBXRSBIQVZFOgo4NSBkaWZmZXJlbnQgc3VidXJicwo2IGNvbXBsYWludCB0eXBlcwoyIGFuaW1hbCB0eXBlcwoKV2Ugd2FudCB0byBicmVhayBpdCBkb3duIGJ5IHN1YnVyYiBhbmQgY29tcGxhaW50IHR5cGUsIGFuZCB0aGVuIGJ5IHN1YnVyYiBhbmQgYW5pbWFsIHR5cGUKYGBge3J9CmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIGZpbGwgPSBhbmltYWxfdHlwZSkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgKwogIGNvb3JkX2ZsaXAoKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShndWlkZSA9IGd1aWRlX2F4aXMobi5kb2RnZSA9IDUpKQpgYGAKCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCBmaWxsID1jb21wbGFpbnRfdHlwZSkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJmaWxsIikgCiAgI2Nvb3JkX2ZsaXAoKSArCiAgI3NjYWxlX3hfZGlzY3JldGUoZ3VpZGUgPSBndWlkZV9heGlzKG4uZG9kZ2UgPSA1KSkKYGBgCgpUaGUgY2hhbGxlbmdlIGFnYWluLCBpcyBoYXZpbmcgdG9vIG1hbnkgc3VidXJicyB0aGF0IHdlIGNhbid0IGdldCBhbnkgdXNlZnVsIGluZm9ybWF0aW9uIG91dCBvZiB0aGUgZ3JhcGhzCgpgYGB7cn0KYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIGNvdW50KHNvcnQgPSBUUlVFKQoKIyBsZXQncyBkcm9wIGFueSBzdWJ1cmJzIHdpdGggbGVzcyB0aGFuIDIwMCBjYXNlcwoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgYW5pbWFsX3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCB5ID0gY291bnQsIGZpbGwgPSBhbmltYWxfdHlwZSkpICsKICBnZW9tX2NvbCgpICsKICBjb29yZF9mbGlwKCkKYGBgCgpUaGUgaGlnaGVzdCBjb3VudCBieSBxdWl0ZSBhIGxhcmdlIG1hcmdpbiBpcyB1bmFsbG9jYXRlZCB0byBhIHNwZWNpZmljIHN1YnVyYi4KCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBhbmltYWxfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA+PSA1MDApICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIHkgPSBjb3VudCwgZmlsbCA9IGFuaW1hbF90eXBlKSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSArCiAgY29vcmRfZmxpcCgpIApgYGAKQXQgYSBnbGFuY2UsIHRoZXJlJ3Mgbm8gYmlnIGRpZmZlcmVuY2Ugb24gYW5pbWFsIHR5cGVzLiBBbGwgdGhlIHN1YnVyYnMgaGF2ZSBhIGxhcmdlIG1ham9yaXR5IG9mIGRvZ3MuIENvdWxkIHdlIGRvIGEgaHlwb3RoZXNpcyB0ZXN0IHRvIHNlZSBpZiB0aGVyZSBpcyBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZT8KCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBhbmltYWxfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA8IDUwMCAmIGNvdW50ID4gMTAwKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCB5ID0gY291bnQsIGZpbGwgPSBhbmltYWxfdHlwZSkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikgKwogIGNvb3JkX2ZsaXAoKSAKYGBgCkxvb2tpbmcgYXQgdGhlIGxvd2VyIGVuZCBvZiB0aGUgcG9wdWxhdGlvbiwgd2Ugc2VlIGFuIG91dGxpZXIuIFRvd25zdmlsbGUgQ2l0eSBoYXMgd2F5IG1vcmUgY2F0cyB0aGFuIGFueSBvZiB0aGUgb3RoZXIgc3VidXJicy4gSW4gZmFjdCwgaXQncyBhbG1vc3QgNTAvNTAhCgpOb3cgc3RpbGwgbG9va2luZyBhdCB0aGUgVG93bnN2aWxsZSBkYXRhc2V0LCB3ZSdsbCBicmVhayBpdCBkb3duIGJ5IGNvbXBsYWludCB0eXBlOgpgYGB7cn0KYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgY29tcGxhaW50X3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwICYgY291bnQgPD0gNDAwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgCmBgYAoKTm93IGZvciB0aGUgbG93ZXIgZW5kIG9mIHRoZSBjb3VudDoKYGBge3J9CmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShzdWJ1cmIpICU+JSAKICBzdW1tYXJpc2UoY291bnQgPSBuKCksIGNvbXBsYWludF90eXBlKSAlPiUgCiAgZmlsdGVyKGNvdW50IDwgNTAwICYgY291bnQgPiA1MCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgCmBgYAoKSSdtIG5vdCBzdXJlIG11Y2ggY2FuIGJlIGdsZWFtZWQgd2l0aCBzbyBtYW55IGNvbXBsYWludF90eXBlcy4gTGV0J3MgdHJ5IGZvY3VzaW5nIG1vcmUgc3BlY2lmaWNhbGx5LgoKT25lIHRoaW5nIHRvIG5vdGUgaGVyZSwgaXMgdGhlIHZhc3QgdmFyaWF0aW9uIGluIHRvbGVyYW5jZSBmb3Igbm9pc2UuIE1vc3QgY2F0ZWdvcmllcyBhcmUgY29uc2lzdGVudCBleGNlcHQgdGhpcyBvbmUuIENsdWRlbiBmb3IgZXhhbXBsZSBoYXMgYSBzbWFsbCBwZXJjZW50YWdlIG9mIG5vaXNlIGNvbXBsYWludHMsd2hpbGUgQm9obGUgUGxhaW5zIGhhcyBhIGh1Z2UgcGVyY2VudGFnZS4gVGhpcyByZXF1aXJlcyBtb3JlIGludmVzdGlnYXRpb24gdG8gZmlndXJlIG91dCB0aGUgcm9vdCBjYXVzZSBvZiB0aGlzOiAKCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA+PSA1MDApICU+JSAKICBmaWx0ZXIoY29tcGxhaW50X3R5cGUgPT0gIk5vaXNlIiB8IChjb21wbGFpbnRfdHlwZSA9PSAiQXR0YWNrIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIHkgPSBjb3VudCwgZmlsbCA9IGNvbXBsYWludF90eXBlKSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSArCiAgY29vcmRfZmxpcCgpIAoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgY29tcGxhaW50X3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwKSAlPiUgCiAgZmlsdGVyKGNvbXBsYWludF90eXBlID09ICJOb2lzZSIgfCAoY29tcGxhaW50X3R5cGUgPT0gIkFnZ3Jlc3NpdmUgQW5pbWFsIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIHkgPSBjb3VudCwgZmlsbCA9IGNvbXBsYWludF90eXBlKSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSArCiAgY29vcmRfZmxpcCgpIAoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgY29tcGxhaW50X3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwKSAlPiUgCiAgZmlsdGVyKGNvbXBsYWludF90eXBlID09ICJXYW5kZXJpbmciIHwgKGNvbXBsYWludF90eXBlID09ICJBZ2dyZXNzaXZlIEFuaW1hbCIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCB5ID0gY291bnQsIGZpbGwgPSBjb21wbGFpbnRfdHlwZSkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikgKwogIGNvb3JkX2ZsaXAoKSAKCmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShzdWJ1cmIpICU+JSAKICBzdW1tYXJpc2UoY291bnQgPSBuKCksIGNvbXBsYWludF90eXBlKSAlPiUgCiAgZmlsdGVyKGNvdW50ID49IDUwMCkgJT4lIAogIGZpbHRlcihjb21wbGFpbnRfdHlwZSA9PSAiRW5jbG9zdXJlIiB8IChjb21wbGFpbnRfdHlwZSA9PSAiTm9pc2UiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgCmBgYAoKRm9yIHRoZSBsZXNzIHRoYW4gNTAwIGdyZWF0ZXIgdGhhbiA1MCBncm91cHM6CmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA8IDUwMCAmIGNvdW50ID4gMTAwKSAlPiUgCiAgZmlsdGVyKGNvbXBsYWludF90eXBlID09ICJOb2lzZSIgfCAoY29tcGxhaW50X3R5cGUgPT0gIkF0dGFjayIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc3VidXJiLCB5ID0gY291bnQsIGZpbGwgPSBjb21wbGFpbnRfdHlwZSkpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9ICJmaWxsIikgKwogIGNvb3JkX2ZsaXAoKSAKCmFuaW1hbF9jb21wbGFpbnRzICU+JSAKICBncm91cF9ieShzdWJ1cmIpICU+JSAKICBzdW1tYXJpc2UoY291bnQgPSBuKCksIGNvbXBsYWludF90eXBlKSAlPiUgCiAgZmlsdGVyKGNvdW50IDwgNTAwICYgY291bnQgPiAxMDApICU+JSAgCiAgZmlsdGVyKGNvbXBsYWludF90eXBlID09ICJOb2lzZSIgfCAoY29tcGxhaW50X3R5cGUgPT0gIkFnZ3Jlc3NpdmUgQW5pbWFsIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzdWJ1cmIsIHkgPSBjb3VudCwgZmlsbCA9IGNvbXBsYWludF90eXBlKSkgKwogIGdlb21fY29sKHBvc2l0aW9uID0gImZpbGwiKSArCiAgY29vcmRfZmxpcCgpIAoKYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwgY29tcGxhaW50X3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPCA1MDAgJiBjb3VudCA+IDEwMCkgJT4lIAogIGZpbHRlcihjb21wbGFpbnRfdHlwZSA9PSAiV2FuZGVyaW5nIiB8IChjb21wbGFpbnRfdHlwZSA9PSAiQWdncmVzc2l2ZSBBbmltYWwiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgCgphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSkgJT4lIAogIGZpbHRlcihjb3VudCA8IDUwMCAmIGNvdW50ID4gMTAwKSAlPiUgCiAgI2ZpbHRlcihjb21wbGFpbnRfdHlwZSA9PSAiRW5jbG9zdXJlIiB8IChjb21wbGFpbnRfdHlwZSA9PSAiTm9pc2UiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHN1YnVyYiwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpICsKICBjb29yZF9mbGlwKCkgKwogIGZhY2V0X3dyYXAofiBzdWJ1cmIpCmBgYAoKCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSwgYW5pbWFsX3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPCA1MDAgJiBjb3VudCA+IDEwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbXBsYWludF90eXBlLCB5ID0gY291bnQsIGZpbGwgPSBjb21wbGFpbnRfdHlwZSkpICsKICBnZW9tX2NvbCgpICsKICBmYWNldF93cmFwKH4gc3VidXJiKQpgYGAKCkZyb20gdGhpcyBncmFwaCwgd2UgY2FuIHNlZSB0aGF0IEh5ZGUgUGFyayBoYXMgYSBkaXNwcm9wb3J0aW9uYXRlIGFtb3VudCBvZiBwcml2YXRlIGltcG91bmRzLCB3aGlsZSBCb2hsZSBwbGFpbnMgaGFzIG1vcmUgbm9pc2UgY29tcGxhaW50cy4KClBvdGVudGlhbCBoeXBvdGhlc2lzIHRlc3Q6CgpUaGF0IHRoZSBsZXZlbCBvZiBwcml2YXRlIGltcG91bmRzIGluIEh5ZGUgUGFyayBiZWluZyBncmVhdGVyIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQuCgpUaGF0IHRoZSBsZXZlbCBvZiBub2lzZSBpbiBCb2hsZSBQbGFpbnMgYmVpbmcgZ3JlYXRlciBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LgpgYGB7cn0KYW5pbWFsX2NvbXBsYWludHMgJT4lIAogIGdyb3VwX2J5KHN1YnVyYikgJT4lIAogIGNvdW50KCkgJT4lIAogIGZpbHRlcihuIDwgNTAwICYgbiA+IDEwMCkKYGBgCgoKCgoKCkxldCdzIGxvb2sgYXQgdGhlIHN1YnVyYnMgd2l0aCBtdWNoIGhpZ2hlciBjb21wbGFpbnRzIG5vdzoKCmBgYHtyfQphbmltYWxfY29tcGxhaW50cyAlPiUgCiAgZ3JvdXBfYnkoc3VidXJiKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCBjb21wbGFpbnRfdHlwZSwgYW5pbWFsX3R5cGUpICU+JSAKICBmaWx0ZXIoY291bnQgPj0gNTAwICYgY291bnQgPDQwMDApICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb21wbGFpbnRfdHlwZSwgeSA9IGNvdW50LCBmaWxsID0gY29tcGxhaW50X3R5cGUpKSArCiAgZ2VvbV9jb2woKSArCiAgZmFjZXRfd3JhcCh+IHN1YnVyYikKYGBgCgoKCgoKIyMjIDIuIGEpIElzIHRoZXJlIGFyZSBhIHRyZW5kIGluIGluanVyaWVzIEJ5IFJlZ2lvbiwgYW5kIGlzIHRoZXJlIGRpZmZlcmVudCBwZWFrcyBvZiB0aW1lcyBvZiB5ZWFyIHBlciByZWdpb24/CgpJdCdzIGltcG9zc2libGUgdG8gc2F5IGlmIHRoZXJlJ3MgZGlmZmVyZW50IHBlYWtzIG9mIHRpbWVzIG9mIHllciBwZXIgcmVnaW9uLCBhcyB3ZSBvbmx5IGhhdmUgdGhlIGRhdGEgZm9yIHRoZSB5ZWFyIGFzIGEgd2hvbGUuIFVubGVzcyB3ZSBsb29rIGF0IFN1YnVyYiByYXRoZXIgdGhhbiByZWdpb24sIGFuZCBicmVhayB0aGlzIGRvd24gYnkgdGltZS4gSG93ZXZlciwgSSB0aGluayBpdCdkIGJlIGdvb2QgdG8gdXNlIHRoZSBnZW5lcmFsIEF1dHJhbGlhIChuYXRpb253aWRlKSBkYXRhLgoKCgoKCgoKCgpgYGB7cn0KYW5pbWFsX291dGNvbWVzICU+JSAKICBncm91cF9ieShyZWdpb24pICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByZWdpb24sIHkgPSBudW1iZXJfb2Zfb2NjdXJlbmNlcywgZmlsbCA9IG91dGNvbWUsIGNvbCA9IG91dGNvbWUpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZmlsbCIpCmBgYAoKCmBgYHtyfQphbmltYWxfb3V0Y29tZXMgJT4lIAogIGdyb3VwX2J5KHJlZ2lvbiwgeWVhcikgJT4lIAogIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHllYXIsIHkgPSBjb3VudCkpICsKICAjZ2VvbV9wb2ludCgpICsKICBnZW9tX2xpbmUoKSArCiAgZmFjZXRfd3JhcCh+IHJlZ2lvbikKYGBgCgoKCgoKCgoKCgoKCgoKCgoKCgo=